//
// Created by 李光辉 on 2020/12/31.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>

#define NELEM 5

typedef struct
{
    char pt;
    double pos[3];
    double orientation[3][3];
}Particle;

int main()
{
    int comm_sz;
    int my_rank;
    int source=0;
    int tag=1;
    int i,j,k;
    MPI_Status stat;

    Particle p[NELEM],particles[NELEM];
    MPI_Datatype particletype;
#项目类型
    MPI_Datatype oldtype[3]={MPI_CHAR,MPI_DOUBLE,MPI_DOUBLE};
#个数
    int blockcount[3]={1,3,9};
#偏移
    MPI_Aint offset[3];

    MPI_Init(NULL,NULL);
    MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
    MPI_Comm_size(MPI_COMM_WORLD,&comm_sz);

    MPI_Address(&(particles[0].pt),&offset[0]);
    MPI_Address(particles[0].pos,&offset[1]);
    MPI_Address(particles[0].orientation,&offset[2]);

    for(i=2;i>=0;i--)
        offset[i]-=offset[0];

    MPI_Type_struct(3,blockcount,offset,oldtype,&particletype);
    MPI_Type_commit(&particletype);

    if(my_rank == 0)
    {
        for(i=0;i<NELEM;i++)
        {
            particles[i].pt = 'H';

            particles[i].pos[0] = 0.0;
            particles[i].pos[1] = 1.0;
            particles[i].pos[2] = 2.0;

            for(j=0;j<3;j++)
                for(k=0;k<3;k++)
                    particles[i].orientation[j][k]=0.99;
        }

        for(i=1;i<comm_sz;i++)
        {
            MPI_Send(particles,NELEM,particletype,i,tag,MPI_COMM_WORLD);
        }
    }
    else
    {
        MPI_Recv(p,NELEM,particletype,source,tag,MPI_COMM_WORLD,&stat);

        printf("%d \n",p[2].pt);
        printf("%f %f %f \n",p[2].pMPI_Type_struct(5,blockcount,offset,oldtype,&particletype);os[0],p[2].pos[1],p[2].pos[2]);
        for(i=0;i<3;i++)
        {
            for(j=0;j<3;j++)
            {
                printf("%f ",p[2].orientation[i][j]);
            }
            printf("\n");
        }
        printf("\n");
    }
    MPI_Finalize();
    return 0;
}
